import { _decorator, Camera, Component, game, Node, Size, UITransform, Widget } from 'cc';
const { ccclass, property, requireComponent } = _decorator;

@ccclass('UIRootController')
@requireComponent(UITransform)
export class UIRootController extends Component {
    private static _instance: UIRootController = null!;
    public static get instance(): UIRootController {
        return UIRootController._instance;
    }

    public static Event = {
        ROOT_SIZE_CHANGED: "root_size_changed",
    }

    @property
    designResolutionWidth: number = 1334;

    @property
    designResolutionHeight: number = 750;

    @property
    maxWidth: number = 1334;

    @property
    maxHeight: number = 750;

    private _uiTransform: UITransform = null!;
    private _viewSize: Size = new Size();
    private _uiSize: Size = new Size();
    private _running: boolean = false;

    public get isRunning(): boolean {
        return this._running;
    }

    public get viewSize(): Readonly<Size> {
        return this._viewSize;
    }

    public get uiSize(): Readonly<Size> {
        return this._uiSize;
    }

    protected onLoad(): void {
        this._running = false;
        UIRootController._instance = this;
        this._uiTransform = this.node.getComponent(UITransform)!;
        this._uiTransform.setAnchorPoint(0.5, 0.5);
        const widget = this.node.getComponent(Widget);
        if (widget != null) widget.enabled = false;

        this.node.on(Node.EventType.PARENT_CHANGED, this.onParentChanged, this);
        this.node.parent.on(Node.EventType.SIZE_CHANGED, this.onParentSizeChanged, this);
        this.onParentSizeChanged();
    }

    protected onDestroy(): void {
        if (UIRootController._instance === this) {
            UIRootController._instance = null!;
        }
        this.node.off(Node.EventType.PARENT_CHANGED, this.onParentChanged, this);
        if (this.node.parent !== null)
            this.node.parent.off(Node.EventType.SIZE_CHANGED, this.onParentSizeChanged, this);
    }

    private onParentChanged(oldParent: Node) {
        if (oldParent!== null)
            oldParent.off(Node.EventType.SIZE_CHANGED, this.onParentSizeChanged, this);

        if (this.node.parent!== null) {
            this.node.parent.on(Node.EventType.SIZE_CHANGED, this.onParentSizeChanged, this);
            this.onParentSizeChanged();
        }
    }

    private onParentSizeChanged() {
        this._running = false;
        let uiTransform = this.node.parent!.getComponent(UITransform);
        if (uiTransform === null) {
            return console.error("ViewportController's parent node must have a UITransform component!");
        }
        this._running = true;
        const viewWidth = uiTransform.width;
        const viewHeight = uiTransform.height;
        let width = viewWidth;
        let height = viewHeight;
        if (width > this.maxWidth) {
            width = this.maxWidth;
        }
        if (height > this.maxHeight) {
            height = this.maxHeight;
        }
        this._viewSize.set(viewWidth, viewHeight);
        this._uiSize.set(width, height);
        this._uiTransform.setContentSize(width, height);
        game.emit(UIRootController.Event.ROOT_SIZE_CHANGED);
    }
}